package net.sf.rose.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import net.sf.rose.jdbc.ConstantCode;

/**
 * 类说明：通用对象操作类
 * 
 * @author fengjian
 * @since 2016/05/09
 */
public class DataUtils {

	private static Logger LOG = Logger.getLogger(DataUtils.class);

	/**
	 * 将字符串转换成指定的数据类型
	 * 
	 * @param type  待转换的值类型
	 * @param value 待转换的值
	 * @return 转换后的对象
	 */
	public static Object convertValue(String type, Object value) {
		if (type.equals(ConstantCode.JAVA_TYPE_STRING)) {
			// 如果是科学计数，则使用工具转换成字符串
			if (value instanceof Double) {
				DecimalFormat df = new DecimalFormat("0");
				return df.format(value);
			} else {
				return value.toString();
			}
		} else if (type.equals(ConstantCode.JAVA_TYPE_INTEGER) || type.equals(ConstantCode.JAVA_TYPE_INTEGER2)) {
			String str = value.toString();
			int index = str.indexOf('.');
			if (index != -1) {
				str = str.substring(0, index);
			}
			value = Integer.parseInt(str);
			return value;
		} else if (type.equals(ConstantCode.JAVA_TYPE_LONG) || type.equals(ConstantCode.JAVA_TYPE_LONG2)) {
			value = Long.parseLong(value.toString());
			return value;
		} else if (type.equals(ConstantCode.JAVA_TYPE_DOUBLE) || type.equals(ConstantCode.JAVA_TYPE_DOUBLE2)) {
			value = Double.parseDouble(value.toString());
			return value;
		} else if (type.equals(ConstantCode.JAVA_TYPE_BIGDECIMAL)) {
			value = new BigDecimal(value.toString());
			return value;
		} else if (type.equals(ConstantCode.JAVA_TYPE_DATE)) {
			String s = value.toString().trim();
			if (s.length() == 0) {
				return null;
			}
			DateFormat df = new DateFormat();
			value = df.format(s);
			return value;
		} else if (type.equals(ConstantCode.JAVA_TYPE_BOOLEAN) || type.equals(ConstantCode.JAVA_TYPE_BOOLEAN2)) {
			if (value.toString().equals("1")) {
				return true;
			}
			if (value.equals("true")) {
				return true;
			}
			if (value.equals("false")) {
				return false;
			}
			return false;
		}
		return value;
	}

	/**
	 * 将Map类型的数据转换成对象实体类
	 * 
	 * @param <T>   返回对象类型
	 * @param clazz - 目标实体类
	 * @param data  - 源数据键值对
	 * @return 转化后的对象实体类
	 */
	@SuppressWarnings("unchecked")
	public static <T> T convertBean(Class<?> clazz, Map<String, Object> data) {
		T object = null;
		try {
			object = (T) clazz.newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
		BeanWrapper bw = new BeanWrapper(object);
		for (String name : bw.getAllFieldNames()) {
			Object val = data.get(name);
			if (val != null) {
				String s = val.toString().trim();
				if (!s.equals("")) {
					bw.set(name, val);
				}
			}
		}
		return object;
	}

	/**
	 * 将对象转换成Map类型
	 * 
	 * @param bean
	 * @return
	 */
	public static Map<String, Object> convertMap(Object bean) {
		Map<String, Object> data = new HashMap<>();
		Class<?> clazz = bean.getClass();
		try {
			while (clazz != Object.class) {
				for (Field f : clazz.getDeclaredFields()) {
					f.setAccessible(true);
					Object obj = f.get(bean);
					if (obj != null) {
						data.put(f.getName(), obj);
					}
				}
				clazz = clazz.getSuperclass();
			}
		} catch (Exception e) {
			LOG.warn(e.getMessage(), e);
		}
		return data;
	}

	/**
	 * 功能：对象间属性复制，只复制非空值。
	 * 
	 * @param source 源对象
	 * @param target 目标对象
	 */
	public static void copy(Object source, Object target) {
		if (source == null || target == null) {
			return;
		}
		Object val = null;
		String str = null;
		BeanWrapper s = new BeanWrapper(source);
		BeanWrapper t = new BeanWrapper(target);
		for (String name : s.getAllFields().keySet()) {
			val = s.get(name);
			if (val != null) {
				str = val.toString();
				if (!str.equals("")) {
					t.set(name, val);
				}
			}
		}
	}

	/**
	 * 功能：用序列化的方法复制对象
	 * 
	 * @param source 源对象
	 * @return 复制得到对象
	 */
	public static Object clone(Object source) {
		try {
			// 读对象，反序列化
			ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
			ObjectOutputStream out = new ObjectOutputStream(byteOut);
			out.writeObject(source);
			// 写对象，序列化
			ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
			ObjectInputStream in = new ObjectInputStream(byteIn);
			return in.readObject();
		} catch (Exception e) {
			String str = "数据克隆失败！\n" + e.getMessage();
			LOG.error(str, e);
			throw new RoseRuntimeException(str);
		}
	}

	/**
	 * 功能：根据类名获得类的Class
	 * 
	 * @param caller    调用者类定义
	 * @param className 类名称
	 * @return 类的Class描述
	 */
	public static Class<?> forName(Class<?> caller, String className) {
		try {
			return Class.forName(className, true, caller.getClassLoader());
		} catch (Exception e) {
			String str = "类className(" + className + ")找不到！\n" + e.getMessage();
			LOG.error(str, e);
			throw new RoseRuntimeException(str);
		}
	}

	/**
	 * 功能：根据类名获得类的对象实体
	 * 
	 * @param <T>       返回的某个值
	 * @param caller    调用者类定义
	 * @param className - 类名称
	 * @return 类的对象实体
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getInstance(Class<?> caller, String className) {
		try {
			return (T) forName(caller, className).newInstance();
		} catch (Exception e) {
			String str = "类className(" + className + ")找不到！\n" + e.getMessage();
			LOG.error(str, e);
			throw new RoseRuntimeException(str);
		}
	}

	/**
	 * 功能：根据类名获得类的对象实体
	 * 
	 * @param <T>       返回的某个值
	 * @param caller    调用者类定义
	 * @param className - 类名称
	 * @return 类的对象实体
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getInstance(Class<?> caller, Class<?> clazz) {
		try {
			return (T) clazz.newInstance();
		} catch (Exception e) {
			String str = "类className(" + clazz.getName() + ")找不到！\n" + e.getMessage();
			LOG.error(str, e);
			throw new RoseRuntimeException(str);
		}
	}

	/**
	 * 功能：判断二个值是否相等，包括空值
	 * 
	 * @param o1 源对象
	 * @param o2 比较对象
	 * @return 是否等值
	 */
	public static boolean equals(Object o1, Object o2) {
		if (o1 == null) {
			return o2 == null ? true : false;
		} else {
			return o1.equals(o2);
		}
	}

	/**
	 * 功能：判断参数是否为空，为空字符串，为"null"字符串。
	 * 
	 * @param arg 参数
	 * @return 是否是空值
	 */
	public static boolean isNullEmpty(Object arg) {
		if (arg == null) {
			return true;
		} else if (arg.equals("")) {
			return true;
		} else if (arg.equals("null")) {
			return true;
		}
		return false;
	}

	/**
	 * 功能：与isNullEmpty方法返回值相反
	 * 
	 * @param arg 参数
	 * @return 是否是非空值
	 */
	public static boolean isNotNullEmpty(Object arg) {
		return !isNullEmpty(arg);
	}

	/**
	 * 功能：清空字符串中的\t'"这三种字符
	 * 
	 * @param string 源字符串
	 * @return 被清除的字符串
	 */
	public static String clearMark(String string) {
		string = string.replace('\t', ' ');
		string = string.replace('\'', ' ');
		string = string.replace('\"', ' ');
		string = StringUtils.deleteWhitespace(string);
		return string;
	}

	/**
	 * 功能：清空字符串中的，$这三种字符
	 * 
	 * @param string 源字符串
	 * @return 被清除的字符串
	 */
	public static String clearNumber(Object string) {
		String str = string.toString();
		str = StringUtils.deleteWhitespace(str);
		str = StringUtils.remove(str, ',');
		str = StringUtils.remove(str, '$');
		return str;
	}

	/**
	 * 功能：使用正则表达式判断参数是否是标准的邮件地址格式。
	 * 
	 * @param string 源字符串
	 * @return 是否符合邮件格式
	 */
	public static boolean isEmail(String string) {
		if (string == null)
			return false;
		String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
		Pattern p;
		Matcher m;
		p = Pattern.compile(regEx1);
		m = p.matcher(string);
		if (m.matches())
			return true;
		else
			return false;
	}

	/**
	 * 功能：将流数据转换成字节数组。
	 * 
	 * @param inStream 流数据
	 * @return 字节数组
	 */
	public static final byte[] inputStreamToByte(InputStream inStream) {
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[4096];
		int rc = 0;
		try {
			while ((rc = inStream.read(buff, 0, 4096)) > 0) {
				swapStream.write(buff, 0, rc);
			}
			return swapStream.toByteArray();
		} catch (Exception e) {
			throw new RoseRuntimeException(e);
		}
	}

	/**
	 * 将字节数组转整形数值
	 * 
	 * @param b
	 * @return
	 */
	public static int byteArrayToInt(byte[] b) {
		return (b[0] << 24) + ((b[1] & 0xFF) << 16) + ((b[2] & 0xFF) << 8) + (b[3] & 0xFF);
	}

	/**
	 * 将短整形数据转成字节数组
	 * 
	 * @param s
	 * @return
	 */
	public static byte[] shortToByteArray(short s) {
		byte[] shortBuf = new byte[2];
		for (int i = 0; i < 2; i++) {
			int offset = (shortBuf.length - 1 - i) * 8;
			shortBuf[i] = (byte) ((s >>> offset) & 0xff);
		}
		return shortBuf;
	}

	/**
	 * 将短整形数据转成字节数组
	 * 
	 * @return
	 */
	public static BigDecimal addBigDecimal(BigDecimal d1, BigDecimal d2) {
		if (d1 == null) {
			if (d2 == null) {
				return new BigDecimal(0);
			} else {
				return d2;
			}
		} else {
			if (d2 == null) {
				return d1;
			} else {
				return d1.add(d2);
			}
		}
	}

}
